package com.rawchen.util;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.security.SignatureException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Collection;
import java.util.Date;

/**
 * @Description: JWT工具类
 */
@Component
public class JwtUtils {
	private static long expireTime;
	private static final byte[] secretKey = Keys.secretKeyFor(SignatureAlgorithm.HS512).getEncoded();

	// @Value("${token.secretKey}")
	// public void setSecretKey(String secretKey) {
	// 	JwtUtils.secretKey = secretKey;
	// }

	@Value("${token.expireTime}")
	public void setExpireTime(long expireTime) {
		JwtUtils.expireTime = expireTime;
	}

	/**
	 * 生成token
	 *
	 * @param subject
	 * @return
	 */
	public static String generateToken(String subject) {
		return Jwts.builder()
				.setSubject(subject)
				.setExpiration(new Date(System.currentTimeMillis() + expireTime))
				.signWith(generalKey(), SignatureAlgorithm.HS512)
				.compact();
	}

	/** 生成加密后的secretKey */
	public static SecretKey generalKey() {
		// byte[] encodeKey = Base64.getDecoder().decode(JWT_KEY);
		// byte[] encodeKey = secretKey.getBytes(StandardCharsets.UTF_8);
		return new SecretKeySpec(secretKey, SignatureAlgorithm.HS512.getJcaName());
	}

	/**
	 * 生成带角色权限的token
	 *
	 * @param subject
	 * @param authorities
	 * @return
	 */
	public static String generateToken(String subject, Collection<? extends GrantedAuthority> authorities) {
		StringBuilder sb = new StringBuilder();
		for (GrantedAuthority authority : authorities) {
			sb.append(authority.getAuthority()).append(",");
		}
		return Jwts.builder()
				.setSubject(subject)
				.claim("authorities", sb)
				.setExpiration(new Date(System.currentTimeMillis() + expireTime))
				.signWith(generalKey(), SignatureAlgorithm.HS512)
				.compact();
	}

	/**
	 * 生成自定义过期时间token
	 *
	 * @param subject
	 * @param expireTime
	 * @return
	 */
	public static String generateToken(String subject, long expireTime) {
		return Jwts.builder()
				.setSubject(subject)
				.setExpiration(new Date(System.currentTimeMillis() + expireTime))
				.signWith(generalKey(), SignatureAlgorithm.HS512)
				.compact();
	}


	/**
	 * 获取tokenBody同时校验token是否有效（无效则会抛出异常）
	 */
	public static Claims getTokenBody(String token) {
		try {
			return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody();
		} catch (SignatureException e) {
			// 服务器重启的话密钥会改变，用原先生成的token解析也就会抛异常
			return null;
		}
	}
}